#include "queue.h"


/**
***********************************************************************
* @brief   初始化队列
* @param   Queue *queue, size_t capacity
* @retval  
* @note  
***********************************************************************
*/
void initQueue(Queue *queue, size_t capacity)
{
	queue->data = (int *)malloc(sizeof(int) * capacity);//队列内存空间申请
	/*判断内存空间是否申请成功*/
	if(queue->data == NULL)
	{
		printf("队列内存申请失败\n");
		return;
	}
	printf("队列内存空间申请成功\n");
	queue->capacity = capacity;
	queue->length = 0;
	queue->front = 0;
	queue->rear = 0;
	printf("队列初始化成功\n");
}

/**
***********************************************************************
* @brief   返回队列内元素个数
* @param   const Queue *queue
* @retval  队列元素长度
* @note  
***********************************************************************
*/
size_t getSize(const Queue *queue)
{
	return queue->length;
}

/**
***********************************************************************
* @brief   队列扩容，动态调整队列大小
* @param   Queue *queue, size_t new_capacity
* @retval  无
* @note  
***********************************************************************
*/
void resizeQueue(Queue *queue, size_t new_capacity)
{
	queue->data = realloc(queue->data, sizeof(int) * new_capacity);//重新调整队列内存大小
	/*判断内存申请是否成功*/
	if(queue->data == NULL)
	{
		printf("队列内存调整失败\n");
		return;
	}
	printf("队列内存调整成功\n");

	queue->capacity = new_capacity;
}
/**
***********************************************************************
* @brief   元素入队列
* @param   Queue *queue, int element
* @retval  
* @note  
***********************************************************************
*/
void enqueue(Queue *queue, int element)
{
	/*判断队列是否存满*/
	if(queue->length == queue->capacity)
	{
		resizeQueue(queue, (queue->capacity + queue->capacity >> 1));//队列内存调整为原来的1.5倍
	}
	queue->data[queue->rear] = element;//元素入队（从队尾入队）
	queue->length ++;//队列长度递增
	queue->rear ++;//记录入队索引位置递增
}

/**
***********************************************************************
* @brief   元素出队列
* @param   Queue *queue
* @retval  返回出队列的元素
* @note  
***********************************************************************
*/
int dequeue(Queue *queue)
{
	/*判断队列是否为空*/
	if(queue->length == 0)//if(queue->rear == queue->front)
	{
		printf("队列已为空，没有可删除的队列元素\n");
		return 0;
	}
	int delete_queue_data = queue->data[queue->front];//将需要出队列的数据存放在delete_queue_data中,始终保持front的值为0
	for(int i = 0; i < queue->length - 1; i++)
	{
		queue->data[i] = queue->data[i + 1];//将队列中的所有元素依次向左移动1位
	}
	queue->length --;//队列长度递减
	queue->rear --;//记录入队索引的位置递减
	return delete_queue_data;//返回出队列的数据
}

/**
***********************************************************************
* @brief   查询队列中元素值
* @param   
* @retval  
* @note  
***********************************************************************
*/
int findQueue(const Queue *queue, size_t index)
{
	/*检查索引是否越界*/
	if(index >= queue->length)
	{
		printf("查询队列元素的索引非法\n");
		return 0;
	}
	return queue->data[index];
}
/**
***********************************************************************
* @brief   释放队列内存
* @param   Queue *queue
* @retval  无
* @note  
***********************************************************************
*/
void destroyQueue(Queue *queue)
{
	/*判断队列是否为空*/
	if(queue->data == NULL)
	{
		printf("队列内存为空，没有可以释放队列内存\n");
		return;
	}
	printf("队列内存不为空，队列内存可以被操作释放\n");
	free(queue->data);//释放队列内存

	queue->data = NULL;//将队列指针设置为空，避免出现野指针
	queue->capacity = 0;
	queue->length = 0;
	queue->rear = 0;
	queue->front = 0;
}

/**
***********************************************************************
* @brief   遍历队列
* @param   Queue *queue
* @retval  
* @note  
***********************************************************************
*/
void printQueue(Queue *queue)
{
	for(int i = 0; i < queue->length; i++)
	{
		printf("%d", queue->data[i]);
		printf("\n");
	}
	printf("\n");
}